/* ellipse is just a trasnformed circle
 */

#include "common/sketchbook.hpp"

constexpr float corner_radius = 14.f;
constexpr float2 half = float2::one(.5f);
const float tau = 2*std::acos(-1);


struct point
{
	enum
	{
		center,
		lower,
		upper,

		count
	};
};

std::array<float2, point::count> points;

float2* dragged_point = nullptr;

bool is_near(float2 corner, float2 position);


void start(Program& program)
{

	program.resizable = true;

	program.draw_once = [](auto frame)
	{
		points[point::center] = frame.size/2;
		points[point::lower] = trand_float2() * frame.size;
		points[point::upper] = trand_float2() * frame.size;
	};

	program.key_up = [&program](scancode code, keycode)
	{
		switch(code)
		{
			case scancode::leftbracket:
			case scancode::c:
				if(pressed(scancode::rctrl) || pressed(scancode::lctrl))
			case scancode::escape:
				program.end();
			break;

			default: break;
		}
	};

	program.mouse_down = [](float2 position, auto)
	{
		for(int i = 0; i < point::count; ++i)
			if(is_near(points[i], position))
				dragged_point = &points[i];
	};

	program.mouse_up = [](auto, auto)
	{
		dragged_point = nullptr;
	};

	program.mouse_move = [](auto, float2 motion)
	{
		if(dragged_point)
			(*dragged_point) += motion;
	};

	program.draw_loop = [](auto frame, auto)
	{

		frame.begin_sketch()
			.rectangle(rect{ frame.size })
			.fill(0xffffff_rgb)
		;

		{ auto sketch = frame.begin_sketch();

			auto transform = geom::vector{
				points[point::lower],
				points[point::upper]
			} - points[point::center];

			auto v = float2::i();
			const auto dencity = 100;
			auto step = common::protractor<>::tau(1.f/dencity);
			sketch.move(transform(v) + points[point::center]);
			for(int i = dencity; i --> 0;)
			{
				v = common::rotate(v,step);
				sketch.vertex(transform(v) + points[point::center]);
			}
			sketch.fill(0xaa00aa_rgb);

		}

		// librarified
		// frame.begin_sketch()
		// 	.ellipse(points[point::center],
		// 		float2x2{
		// 			points[point::lower],
		// 			points[point::upper]
		// 		} - points[point::center]
		// 	)
		// 	.fill(0xaa00aa_rgb)
		// ;

		{ auto sketch = frame.begin_sketch();
			for(int i = 0; i < point::count; ++i)
				sketch.ellipse(rect{float2::one(corner_radius), points[i], half});
			sketch.line_width(1).outline(0x555555_rgb);
		}

	};
}

bool is_near(float2 corner, float2 position)
{
	return (corner - position).magnitude() < corner_radius * corner_radius;
}
